{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.callbacks import ModelCheckpoint,EarlyStopping,ReduceLROnPlateau,TensorBoard\n",
    "from keras.models import Model\n",
    "from keras import backend as K\n",
    "from keras.optimizers import Adam\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import os\n",
    "from losses import bce_dice_loss\n",
    "from rssegnet import RSSegVGGNet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 从训练集取样本\n",
    "# samples_data_root = 'D:/Data/mc_data/train/images/0/'\n",
    "\n",
    "# filenames = np.random.choice(os.listdir(samples_data_root), 1000)\n",
    "# samples = []\n",
    "# for fn in filenames:\n",
    "#     fullname = samples_data_root + fn\n",
    "#     image = Image.open(fullname)\n",
    "#     image_arr = np.array(image)\n",
    "#     samples.append(image_arr)\n",
    "\n",
    "# sample_images = np.array(samples)\n",
    "# print(sample_images.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def adjust_data(img,mask):\n",
    "    mean_ = np.array([96.24618792,104.67673492,99.35844062])\n",
    "    img = (img - mean_) / 255\n",
    "    mask = mask / 255\n",
    "    mask[mask > 0.5] = 1\n",
    "    mask[mask <= 0.5] = 0\n",
    "    return (img,mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_train_generator():\n",
    "    train_data_root = 'D:/Data/AerialImageDataset/train'  # 训练集存放路径\n",
    "\n",
    "    # data augmentation\n",
    "    data_gen_args = dict(rotation_range=180,\n",
    "                        width_shift_range=0.2,\n",
    "                        height_shift_range=0.2,\n",
    "                        shear_range=0.2,\n",
    "                        zoom_range=0.2,\n",
    "                        horizontal_flip=True,\n",
    "                        vertical_flip=True,\n",
    "                        fill_mode='constant',\n",
    "                        cval=0\n",
    "                        )\n",
    "#     data_gen_args = dict()\n",
    "\n",
    "    train_image_datagen = ImageDataGenerator(**data_gen_args)\n",
    "    train_mask_datagen = ImageDataGenerator(**data_gen_args)\n",
    "\n",
    "    seed=1\n",
    "\n",
    "    train_image_generator = train_image_datagen.flow_from_directory(\n",
    "        train_data_root + '/images_clipped',\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='rgb',\n",
    "        save_to_dir=train_data_root + '/images_aug',\n",
    "        save_format='jpeg')\n",
    "\n",
    "    train_mask_generator = train_mask_datagen.flow_from_directory(\n",
    "        train_data_root + '/gt_clipped',\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='grayscale',\n",
    "        save_to_dir=train_data_root + '/masks_aug',\n",
    "        save_format='jpeg')\n",
    "\n",
    "    # combine generators into one which yields image and masks\n",
    "    train_generator = zip(train_image_generator, train_mask_generator)\n",
    "    \n",
    "    for (image, mask) in train_generator:\n",
    "#         print(image.shape)\n",
    "#         print(mask.shape)\n",
    "        yield adjust_data(image, mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_val_generator():\n",
    "    val_data_root = 'D:/Data/AerialImageDataset/val'  # 验证集存放路径\n",
    "    \n",
    "    # data augmentation\n",
    "    # data_gen_args = dict(rotation_range=0.2,\n",
    "    #                     width_shift_range=0.05,\n",
    "    #                     height_shift_range=0.05,\n",
    "    #                     shear_range=0.05,\n",
    "    #                     zoom_range=0.05,\n",
    "    #                     horizontal_flip=True,\n",
    "    #                     fill_mode='nearest')\n",
    "    data_gen_args = dict()\n",
    "\n",
    "    val_image_datagen = ImageDataGenerator(**data_gen_args)\n",
    "    val_mask_datagen = ImageDataGenerator(**data_gen_args)\n",
    "\n",
    "    seed = 1\n",
    "\n",
    "    val_image_generator = val_image_datagen.flow_from_directory(\n",
    "        val_data_root + '/images_clipped',\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='rgb')\n",
    "\n",
    "    val_mask_generator = val_mask_datagen.flow_from_directory(\n",
    "        val_data_root + '/gt_clipped',\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='grayscale')\n",
    "\n",
    "    val_generator = zip(val_image_generator, val_mask_generator)\n",
    "    \n",
    "    for (image, mask) in val_generator:\n",
    "#         print(image.shape)\n",
    "#         print(mask.shape)\n",
    "        yield adjust_data(image, mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "image_input (InputLayer)        (None, 256, 256, 3)  0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_1 (Conv2D)               (None, 256, 256, 64) 1792        image_input[0][0]                \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_2 (Conv2D)               (None, 256, 256, 64) 36928       conv2d_1[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2D)  (None, 128, 128, 64) 0           conv2d_2[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_3 (Conv2D)               (None, 128, 128, 128 73856       max_pooling2d_1[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_4 (Conv2D)               (None, 128, 128, 128 147584      conv2d_3[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2D)  (None, 64, 64, 128)  0           conv2d_4[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_5 (Conv2D)               (None, 64, 64, 256)  295168      max_pooling2d_2[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_6 (Conv2D)               (None, 64, 64, 256)  590080      conv2d_5[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_7 (Conv2D)               (None, 64, 64, 256)  590080      conv2d_6[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2D)  (None, 32, 32, 256)  0           conv2d_7[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_8 (Conv2D)               (None, 32, 32, 512)  1180160     max_pooling2d_3[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_9 (Conv2D)               (None, 32, 32, 512)  2359808     conv2d_8[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_10 (Conv2D)              (None, 32, 32, 512)  2359808     conv2d_9[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2D)  (None, 16, 16, 512)  0           conv2d_10[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_11 (Conv2D)              (None, 16, 16, 512)  2359808     max_pooling2d_4[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_12 (Conv2D)              (None, 16, 16, 512)  2359808     conv2d_11[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_13 (Conv2D)              (None, 16, 16, 512)  2359808     conv2d_12[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_5 (MaxPooling2D)  (None, 8, 8, 512)    0           conv2d_13[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_14 (Conv2D)              (None, 8, 8, 512)    2359808     max_pooling2d_5[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_1 (Conv2DTrans (None, 16, 16, 256)  1179904     conv2d_14[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_1 (Concatenate)     (None, 16, 16, 768)  0           conv2d_transpose_1[0][0]         \n",
      "                                                                 conv2d_13[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_15 (Conv2D)              (None, 16, 16, 512)  3539456     concatenate_1[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_2 (Conv2DTrans (None, 32, 32, 256)  1179904     conv2d_15[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_2 (Concatenate)     (None, 32, 32, 768)  0           conv2d_transpose_2[0][0]         \n",
      "                                                                 conv2d_10[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_16 (Conv2D)              (None, 32, 32, 512)  3539456     concatenate_2[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_3 (Conv2DTrans (None, 64, 64, 128)  589952      conv2d_16[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_3 (Concatenate)     (None, 64, 64, 384)  0           conv2d_transpose_3[0][0]         \n",
      "                                                                 conv2d_7[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_17 (Conv2D)              (None, 64, 64, 256)  884992      concatenate_3[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_4 (Conv2DTrans (None, 128, 128, 64) 147520      conv2d_17[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_4 (Concatenate)     (None, 128, 128, 192 0           conv2d_transpose_4[0][0]         \n",
      "                                                                 conv2d_4[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_18 (Conv2D)              (None, 128, 128, 128 221312      concatenate_4[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_5 (Conv2DTrans (None, 256, 256, 32) 36896       conv2d_18[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_5 (Concatenate)     (None, 256, 256, 96) 0           conv2d_transpose_5[0][0]         \n",
      "                                                                 conv2d_2[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_19 (Conv2D)              (None, 256, 256, 1)  865         concatenate_5[0][0]              \n",
      "==================================================================================================\n",
      "Total params: 28,394,753\n",
      "Trainable params: 28,394,753\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = RSSegVGGNet.build()\n",
    "model.compile(loss=bce_dice_loss, optimizer=Adam(), metrics=['accuracy'])\n",
    "model.summary()\n",
    "model.load_weights(\"building_seg_vgg16_bcedice_0918.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/1000\n",
      "Found 60000 images belonging to 1 classes.\n",
      "Found 60000 images belonging to 1 classes.\n",
      "3749/3750 [============================>.] - ETA: 1s - loss: 0.5261 - acc: 0.9315Found 12000 images belonging to 1 classes.\n",
      "Found 12000 images belonging to 1 classes.\n",
      "3750/3750 [==============================] - 5591s 1s/step - loss: 0.5262 - acc: 0.9315 - val_loss: 0.9074 - val_acc: 0.8621\n",
      "Epoch 2/1000\n",
      "3750/3750 [==============================] - 3532s 942ms/step - loss: 0.6489 - acc: 0.9126 - val_loss: 0.7738 - val_acc: 0.8839\n",
      "Epoch 3/1000\n",
      "3750/3750 [==============================] - 3530s 941ms/step - loss: 0.5908 - acc: 0.9217 - val_loss: 0.7297 - val_acc: 0.8942\n",
      "Epoch 4/1000\n",
      "3750/3750 [==============================] - 3527s 941ms/step - loss: 0.5653 - acc: 0.9256 - val_loss: 0.7296 - val_acc: 0.8911\n",
      "Epoch 5/1000\n",
      "3750/3750 [==============================] - 3526s 940ms/step - loss: 0.5528 - acc: 0.9273 - val_loss: 0.7005 - val_acc: 0.8987\n",
      "Epoch 6/1000\n",
      "3750/3750 [==============================] - 3529s 941ms/step - loss: 0.5514 - acc: 0.9278 - val_loss: 0.7379 - val_acc: 0.8919\n",
      "Epoch 7/1000\n",
      "3750/3750 [==============================] - 3530s 941ms/step - loss: 0.5368 - acc: 0.9298 - val_loss: 0.7269 - val_acc: 0.8911\n",
      "Epoch 8/1000\n",
      "3750/3750 [==============================] - 3534s 942ms/step - loss: 0.5284 - acc: 0.9309 - val_loss: 0.7527 - val_acc: 0.8876\n",
      "Epoch 9/1000\n",
      "3750/3750 [==============================] - 3533s 942ms/step - loss: 0.5275 - acc: 0.9311 - val_loss: 0.6956 - val_acc: 0.8987\n",
      "Epoch 10/1000\n",
      "3750/3750 [==============================] - 3530s 941ms/step - loss: 0.5172 - acc: 0.9324 - val_loss: 0.6575 - val_acc: 0.9082\n",
      "Epoch 11/1000\n",
      "3750/3750 [==============================] - 4069s 1s/step - loss: 0.5149 - acc: 0.9330 - val_loss: 0.7122 - val_acc: 0.8943\n",
      "Epoch 12/1000\n",
      "3750/3750 [==============================] - 3951s 1s/step - loss: 0.5132 - acc: 0.9331 - val_loss: 0.7661 - val_acc: 0.8792\n",
      "Epoch 13/1000\n",
      "3750/3750 [==============================] - 3831s 1s/step - loss: 0.5066 - acc: 0.9339 - val_loss: 0.6842 - val_acc: 0.9009\n",
      "Epoch 14/1000\n",
      "3750/3750 [==============================] - 3550s 947ms/step - loss: 0.5045 - acc: 0.9344 - val_loss: 0.6993 - val_acc: 0.8958\n",
      "Epoch 15/1000\n",
      "3750/3750 [==============================] - 3553s 948ms/step - loss: 0.5021 - acc: 0.9347 - val_loss: 0.6893 - val_acc: 0.9005\n",
      "Epoch 16/1000\n",
      " 829/3750 [=====>........................] - ETA: 45:12 - loss: 0.5078 - acc: 0.9343"
     ]
    }
   ],
   "source": [
    "callback_list = [\n",
    "    EarlyStopping(\n",
    "        monitor='acc',\n",
    "        patience=10,\n",
    "    ),\n",
    "    ModelCheckpoint(\n",
    "        filepath='building_seg_vgg16_bcedice_0918.h5',\n",
    "        monitor='val_loss',\n",
    "        save_best_only=True,\n",
    "    ),\n",
    "    ReduceLROnPlateau(\n",
    "        monitor='val_loss',\n",
    "        factor=0.1,\n",
    "        patience=10,\n",
    "    ),\n",
    "    TensorBoard(\n",
    "        log_dir = 'logs'\n",
    "    ),\n",
    "]\n",
    "\n",
    "history = model.fit_generator(make_train_generator(),\n",
    "                              epochs=1000,\n",
    "                              steps_per_epoch=int(60000/16),\n",
    "                              validation_data=make_val_generator(),\n",
    "                              validation_steps=int(12000/16),\n",
    "                              callbacks=callback_list,\n",
    "                              verbose=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = history.history['acc']\n",
    "val_acc = history.history['val_acc']\n",
    "loss = history.history['loss']\n",
    "val_loss = history.history['val_loss']\n",
    "epochs = range(1, len(acc) + 1)\n",
    "plt.plot(epochs, acc, 'bo', label='Training acc')\n",
    "plt.plot(epochs, val_acc, 'b', label='Validation acc')\n",
    "plt.title('Training and validation accuracy')\n",
    "plt.legend()\n",
    "plt.figure()\n",
    "plt.plot(epochs, loss, 'bo', label='Training loss')\n",
    "plt.plot(epochs, val_loss, 'b', label='Validation loss')\n",
    "plt.title('Training and validation loss')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
